#pragma once
#include "core/strings/BaseString.h"
#include "../util/encoder_type.h"
#include "extdef.h"
#include <map>
#include <vector>
namespace qb{
	namespace base{

		typedef KeyString	StringType;
        class SSPROTOAPI MetaObject{
		public:
			struct FieldInfo{
				kExpectType	type;
				StringType	name;
				int		offset;
				int		size;
			};
			typedef std::vector<FieldInfo> FieldArray;
		protected:
			FieldArray	m_fields;
			int					m_size;
			StringType			m_name;
		public:
			MetaObject(const char* name, int size);
			int  AddField(const char* name, kExpectType type, int offset, int size);
			const FieldArray& GetFields()const{ return m_fields; }
			int  GetSize()const{ return m_size; }
			const StringType& GetName()const{ return m_name; }
		};

        class SSPROTOAPI EncodeBuf{
		public:
			static void Free(char* buf);
			static char* Alloc(int size);
		};
        class SSPROTOAPI SimpleEncoder{
			typedef uint64_t u64;
			typedef std::map<int, MetaObject*>	MetaMap;
			typedef MetaObject::FieldInfo FieldInfo;
			enum{
				BIT_FLAG_DFT = 0x01,
				BIT_FLAG_RAW = 0x02,
				BIT_FLAG_DIFF = 0x04,
				BIT_FLAG_COUNT = 3,
			};
			MetaMap		m_metamap;
		public:
			static SimpleEncoder& Get(){
				static SimpleEncoder sincoder;
				return sincoder;
			}
			SimpleEncoder();
			~SimpleEncoder();
			bool AddMetaObject(int id,MetaObject* meta);


			char*  Encode(const char* data, int size, int id, int& length);
			int Encode(const char* data, int size, int id, char* out, int capcity);
			int Decode(const void* data, int size, char* out, int capcity);
			MetaObject* GetMetaObject(int id);

		protected:

		};

	}//namespace base;
}//namespace qb;
